package com.yunkeji.api.invited.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunkeji.api.invited.bo.BindBo;
import com.yunkeji.api.invited.service.InvitedService;
import com.yunkeji.api.invited.vo.InvitedCount;
import com.yunkeji.api.invited.vo.InvitedVo;
import com.yunkeji.api.invited.vo.QueryDownLoad;
import com.yunkeji.api.user.mapper.ApiAppUserMapper;
import com.yunkeji.common.core.domain.PageQuery;
import com.yunkeji.common.core.domain.dto.PayLogDTO;
import com.yunkeji.common.core.page.TableDataInfo;
import com.yunkeji.common.enums.app.EnableEnum;
import com.yunkeji.common.enums.app.InviteRewardType;
import com.yunkeji.common.enums.app.PayLogTypeEnums;
import com.yunkeji.common.exception.AppServiceException;
import com.yunkeji.common.helper.LoginHelper;
import com.yunkeji.common.msg.PushMessage;
import com.yunkeji.dao.domain.AppUser;
import com.yunkeji.dao.domain.InviteReward;
import com.yunkeji.dao.domain.SysVersion;
import com.yunkeji.dao.mapper.InviteRewardMapper;
import com.yunkeji.dao.mapper.PayLogMapper;
import com.yunkeji.dao.mapper.SysVersionMapper;
import com.yunkeji.dao.mapper.UserInvitedMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;

/** @author 老张 */
@Slf4j
@Service
@AllArgsConstructor
public class InvitedServiceImpl implements InvitedService {

    private final ApiAppUserMapper apiAppUserMapper;

    private final PayLogMapper payLogMapper;

    private final UserInvitedMapper userInvitedMapper;

    private final SysVersionMapper sysVersionMapper;

    private final InviteRewardMapper rewardMapper;

    @Override
    public QueryDownLoad bindPid(HttpServletRequest httpServletRequest) {
        //    String pid = httpServletRequest.getHeader("pid");
        //        String invitedCode = RandomUtil.randomString(16);
        //        if (StrUtil.isNotEmpty(pid) && NumberUtil.isNumber(pid)) {
        //            AppUser appUser = apiAppUserMapper.selectById(pid);
        //            if (appUser != null) {
        //                //                RedisUtils.setCacheObject(
        //                //                        CacheConstants.INVITED +
        // ServletUtils.getClientIP(),
        //                //                        pid,
        //                //                        Duration.ofMinutes(30));
        //                RedisUtils.setCacheObject(
        //                        CacheConstants.INVITED + invitedCode, pid,
        // Duration.ofMinutes(30));
        //            }
        //        }
        SysVersion sysVersion =
                sysVersionMapper.selectOne(
                        Wrappers.lambdaQuery(SysVersion.class)
                                .eq(SysVersion::getValidFlag, EnableEnum.YES.getCode())
                                .orderByDesc(SysVersion::getVersionIndex),
                        false);

        return QueryDownLoad.builder()
                .url(sysVersion != null ? sysVersion.getVersionDownloadUrl() : "")
                //  .invitedCode("")
                .build();
    }

    @Override
    public InvitedCount invitedCount() {

        /**
         * 邀请收益 通话收益+礼物收益
         * @author 老张
         */
        BigDecimal sumWithDraw =
                payLogMapper.sumByType(
                        LoginHelper.getUserId(), PayLogTypeEnums.收益_邀请视频收益.getCode());
        BigDecimal sumGift =
            payLogMapper.sumByType(
                LoginHelper.getUserId(), PayLogTypeEnums.收益_邀请礼物收益.getCode());

        /**
         * 好友充值
         *
         * @author 老张
         */
        BigDecimal sumRecharge =
                payLogMapper.sumByType(
                        LoginHelper.getUserId(), PayLogTypeEnums.收益_邀请充值收益.getCode());
        return InvitedCount.builder()
                .friendsWithDraw(sumWithDraw.add(sumGift))
                .friendsRecharge(sumRecharge)
                .build();
    }
    /**
     * 分页邀请
     *
     * @author 老张
     */
    @Override
    public TableDataInfo<InvitedVo> pageInvited(PageQuery pageQuery) {
        Page<InvitedVo> datas =
                apiAppUserMapper.pageInvited(LoginHelper.getUserId(), pageQuery.build());
        return TableDataInfo.build(datas);
    }

    /**
     * 绑定
     *
     * @author 老张
     */
    @Override
    public void toBind(BindBo bindBo) {
        AppUser appUser = apiAppUserMapper.selectById(bindBo.getUid());
        if (appUser!=null){
            AppUser appUser1 = apiAppUserMapper.selectById(LoginHelper.getUserId());
            if (appUser1.getPid()!=null){
                throw AppServiceException.paramException("该用户已经绑定");
            }else {
                AppUser newUser=new AppUser();
                newUser.setId(LoginHelper.getUserId());
                newUser.setPid(bindBo.getUid());
                apiAppUserMapper.updateById(newUser);
            }
        }
    }

    private BigDecimal inviteRewardHandler(String code, Long traceId, BigDecimal price, Long userId) {
        if(Objects.isNull(userId)){
            return BigDecimal.ZERO;
        }
        InviteReward reward = rewardMapper.selectOne(
            Wrappers.lambdaQuery(InviteReward.class)
                .eq(InviteReward::getCode, code));
        if(Objects.isNull(reward)){
            return BigDecimal.ZERO;
        }
        if(reward.getAmount().doubleValue() > 0){
            BigDecimal amount;
            if(reward.getType().equals(0)){
                amount = reward.getAmount();
            } else {
                amount = reward.getAmount().divide(BigDecimal.valueOf(100),2, RoundingMode.DOWN)
                    .multiply(price).setScale(0, RoundingMode.DOWN);
            }
            if (NumberUtil.isGreaterOrEqual(amount, BigDecimal.ONE)) {
                apiAppUserMapper.logAddDiamondBalance(
                    PayLogDTO.builder()
                        .traceId(traceId)
                        .uid(userId)
                        .changeNum(amount)
                        .serviceTag(reward.getDescription() + ":" + traceId)
                        .logType(PayLogTypeEnums.收益_邀请充值收益)
                        .build());
                return amount;
            }
        }
        return BigDecimal.ZERO;
    }

    @Override
    public void inviteRewardFirst(Long traceId, BigDecimal price, Long userId) {
        BigDecimal amount = inviteRewardHandler(InviteRewardType.被邀请人首充.getCode(), traceId, price, userId);
        if(amount.doubleValue() > 0) {
            PushMessage.sendSysNotify(
                apiAppUserMapper.selectById(userId).getPlatformId(),
                "您邀请的用户已首次充值成功，您获得了" + amount + "钻石奖励，可前往我的钱包查看！");
        }
    }

    @Override
    public void inviteRewardRecharge(Long traceId, BigDecimal price, Long userId) {
        BigDecimal amount = inviteRewardHandler(InviteRewardType.被邀请人充值.getCode(), traceId, price, userId);
        if(amount.doubleValue() > 0) {
            PushMessage.sendSysNotify(
                apiAppUserMapper.selectById(userId).getPlatformId(),
                "您邀请的用户已成功充值，您获得了" + amount + "钻石奖励，可前往我的钱包查看！");
        }
    }
}
